目录前言:一、Top-K问题描述:二、不同解决思路实现:①.排序法:②.直接建堆法:③.K堆法总结:前言: 上篇文章我们学习了二叉树的顺序存储结构,并且对于实际使用中所常用的顺序存储结构——堆的各个接口进行实现。这篇文章我们将对堆的实际应用进行更加深入的研究。一、Top-K问题描述: Top-K问题,就是求数据结合前K个最大的元素或者最小的元素,一般情况下数据量较大。比如:美团上的附近美食排行榜、年纪成绩排行榜等等。 而对于Top-K问题,我们能想到的有三种不同的思路去解决。首先最简单直接的方式就是排序。但是如果需要处理的数据量非常大,排序就不太可取了。而另外两种方法
文章目录重要的概念树的存储方式顺序存储链式存储堆的概念堆的实现向上调整算法一些实现过程中的技巧实现搭建堆实现出堆的操作向下调整算法堆排序TopK重要的概念要讲到堆,先要说两个关于二叉树的概念满二叉树:一个二叉树如果每一层的节点数都是最大值,那么这个二叉树就是满二叉树完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是满二叉树的变形,对于深度为k的树有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中编号从1至n的节点上面所展示的就是满二叉树和完全二叉树树的存储方式顺序存储任何一个数据结构在内存中都要以一定的方式存储起来,那么具体如何存储起来?有下面的规则首先是顺序存储,也就是用
目录前言一.堆的介绍1.堆的本质2.堆的分类二.堆的实现(以小根堆为例)1.关于二叉树的两组重要结论:2.堆的物理存储结构框架(动态数组的简单构建)3.堆元素插入接口(以小根堆为例)堆尾元素向上调整的算法接口:4.堆元素插入接口测试5.堆元素插入接口建堆的时间复杂度分析(建堆时间复杂度)6.堆元素删除接口(同样以小根堆为例子)堆元素向下调整算法接口实现:7.堆元素删除接口测试8.逐个删除堆顶数据过程的时间复杂度分析(删堆的时间复杂度分析)9.堆的实现代码总览(以小根堆为例)10.结语 前言关于数据结构的文章:写博客的时候我感觉在表达层面上有点费劲,如果文章整体在表述上让人感觉不够清楚,恳请读
目录前言一.堆的介绍1.堆的本质2.堆的分类二.堆的实现(以小根堆为例)1.关于二叉树的两组重要结论:2.堆的物理存储结构框架(动态数组的简单构建)3.堆元素插入接口(以小根堆为例)堆尾元素向上调整的算法接口:4.堆元素插入接口测试5.堆元素插入接口建堆的时间复杂度分析(建堆时间复杂度)6.堆元素删除接口(同样以小根堆为例子)堆元素向下调整算法接口实现:7.堆元素删除接口测试8.逐个删除堆顶数据过程的时间复杂度分析(删堆的时间复杂度分析)9.堆的实现代码总览(以小根堆为例)10.结语 前言关于数据结构的文章:写博客的时候我感觉在表达层面上有点费劲,如果文章整体在表述上让人感觉不够清楚,恳请读
目录一.堆排序二.topk问题一.堆排序我们知道冒泡算法的时间复杂度是O(N^2),在数据量很多的时候,N^2是个很可怕的数字,二分算法的时间复杂度是O(logn),但是二分算法有限制条件,实用性并不高,那怎样才能高效实用的排序呢?堆排序就能很好解决上述问题,堆排序的时间复杂度是O(logn),也没啥限制条件,可以实现高效排序。这里要注意,排升序要建大堆,排降序要建小堆;1.假设排升序,所以建大堆;2.堆建好后,定义一个end变量,令其=n-1(数组最后一个元素的下标是n-1);3.堆建好后,数组第一个元素就是最大的,将其与最后一个数据交换,然后这个数据就不需要动了,为了保持它是个大堆,让它的
目录一.堆排序二.topk问题一.堆排序我们知道冒泡算法的时间复杂度是O(N^2),在数据量很多的时候,N^2是个很可怕的数字,二分算法的时间复杂度是O(logn),但是二分算法有限制条件,实用性并不高,那怎样才能高效实用的排序呢?堆排序就能很好解决上述问题,堆排序的时间复杂度是O(logn),也没啥限制条件,可以实现高效排序。这里要注意,排升序要建大堆,排降序要建小堆;1.假设排升序,所以建大堆;2.堆建好后,定义一个end变量,令其=n-1(数组最后一个元素的下标是n-1);3.堆建好后,数组第一个元素就是最大的,将其与最后一个数据交换,然后这个数据就不需要动了,为了保持它是个大堆,让它的
目录一、概念及其介绍二、适用说明三、结构图示四、Java实例代码五.堆和栈的区别一、概念及其介绍堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵完全二叉树的数组对象。堆满足下列性质:堆中某个节点的值总是不大于或不小于其父节点的值。堆总是一棵完全二叉树。二、适用说明堆是利用完全二叉树的结构来维护一组数据,然后进行相关操作,一般的操作进行一次的时间复杂度在 O(1)~O(logn) 之间,堆通常用于动态分配和释放程序所使用的对象。若为优先队列的使用场景,普通数组或者顺序数组,最差情况为 O(n^2),堆这种数据结构也可以提高入队和出队的效率。三、结构图示二叉堆是一颗
目录一、概念及其介绍二、适用说明三、结构图示四、Java实例代码五.堆和栈的区别一、概念及其介绍堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵完全二叉树的数组对象。堆满足下列性质:堆中某个节点的值总是不大于或不小于其父节点的值。堆总是一棵完全二叉树。二、适用说明堆是利用完全二叉树的结构来维护一组数据,然后进行相关操作,一般的操作进行一次的时间复杂度在 O(1)~O(logn) 之间,堆通常用于动态分配和释放程序所使用的对象。若为优先队列的使用场景,普通数组或者顺序数组,最差情况为 O(n^2),堆这种数据结构也可以提高入队和出队的效率。三、结构图示二叉堆是一颗
我想将程序状态存储在文件中。所以我有一个映射文件,我对其执行操作然后保存它,以后可能会使用它。这对于简单的事情很好,但如果我想要一个需要动态内存分配的长期数据结构,我需要一个内存分配器,我可以强制在我映射的页面中分配。我相当肯定我不能用标准的cmalloc做到这一点,而且我查看了jemalloc,但我不知道我是否可以在那里看到任何东西。我不知道我是否走错了路,但有没有any方法可以在使用之前指定堆的位置/大小? 最佳答案 对于这样的事情,您并不真正想要动态内存分配。相反,您想要的是一个使用指向元素的索引值而不是实际指针的数组。假设你
我想将程序状态存储在文件中。所以我有一个映射文件,我对其执行操作然后保存它,以后可能会使用它。这对于简单的事情很好,但如果我想要一个需要动态内存分配的长期数据结构,我需要一个内存分配器,我可以强制在我映射的页面中分配。我相当肯定我不能用标准的cmalloc做到这一点,而且我查看了jemalloc,但我不知道我是否可以在那里看到任何东西。我不知道我是否走错了路,但有没有any方法可以在使用之前指定堆的位置/大小? 最佳答案 对于这样的事情,您并不真正想要动态内存分配。相反,您想要的是一个使用指向元素的索引值而不是实际指针的数组。假设你